/* 
 * Copyright (c) 2004-2005 Massachusetts Institute of Technology. This code was
 * developed as part of the Haystack (http://haystack.lcs.mit.edu/) research 
 * project at MIT. Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files (the 
 * "Software"), to deal in the Software without restriction, including without 
 * limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions: 
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software. 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. 
 */

/*
 * Created on Mar 4, 2005
 */
package edu.mit.csail.relo;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;

import edu.mit.csail.relo.modelBridge.Comment;
import edu.mit.csail.relo.modelBridge.DirectedRel;
import edu.mit.csail.relo.modelBridge.NamedRel;
import edu.mit.csail.relo.parts.CommentEditPart;
import edu.mit.csail.relo.parts.NamedRelationPart;
import edu.mit.csail.relo.store.ReloRdfRepository;
import edu.mit.csail.relo.store.ReloStoreInitializer;
import edu.mit.csail.relo.store.StoreUtil;


/**
 * @author vineet
 *
 */
public class ReloCore implements ReloStoreInitializer {
    static final Logger logger = ReloPlugin.getLogger(ReloCore.class);

    
    private final static String reloRdfNamespace = ReloRdfRepository.reloRdfNamespace;
	public static final String PLUGIN_ID = ReloPlugin.PLUGIN_ID;

    public static final URI createReloURI(String str) {
    	return StoreUtil.createMemURI(reloRdfNamespace + str);
    }

    // system properties
    public static final URI id = createReloURI("core#id");
    public static final URI controller = createReloURI("core#controller");
    public static final URI model = createReloURI("core#model");
    public static final URI initialized = createReloURI("core#initialized");
    public static final URI contains = createReloURI("core#contains");
    public static final URI name = createReloURI("core#name");
    public static final URI reloFile = createReloURI("core#reloFile");

    // types
    public static final URI node = createReloURI("core#node");
    public static final URI detailsNode = createReloURI("core#detailsNode");
    public static final URI link = createReloURI("core#link");
    
    // annotation
    public static final URI annoRel = createReloURI("ann#annoRel");
	public static final URI namedRel = createReloURI("ann#namedRel");
	public static final URI commentType = createReloURI("ann#comment");
	
	// above properties as directed relationships
    public static final DirectedRel fwdContains = DirectedRel.getFwd(contains);
    public static final DirectedRel revContains = DirectedRel.getRev(contains);
	

	// debugging setting
    public static final boolean dumpStatementsOnMouseSelection = false;

    
	public static String encodeId(String key) {
	    return key.replace("_","_un").replace(":","_co").replace("/","_sl").replace("#","_sh");
	}
	public static String decodeId(String key) {
		// in rev order as last time
		return key.replace("_sh","#").replace("_sl","/").replace("_co",":").replace("_un", "_");
	}
    public static Resource idToResource(ReloRdfRepository reloRepo, String namespaceExt, String key)  {
        return reloRepo.getDefaultURI(namespaceExt, key);
	}
    // encode is called when we expect the key to have namespace delimiters: ':', '/' or '#'
    public static Resource encodedIdToResource(ReloRdfRepository reloRepo, String namespaceExt, String key) {
        return idToResource(reloRepo, namespaceExt, encodeId(key));
	}

    public static String resourceToId(ReloRdfRepository reloRepo, Resource res, boolean decodeKey) {
    	String retVal = null;
		retVal = decodeId( ((URI)res).getLocalName() );
	    if (decodeKey) retVal = encodeId(retVal);
		return retVal;
	}


    public static Resource eclipseProjectToRDFResource(ReloRdfRepository reloRepo, IProject proj) {
        if (proj==null) return null;
        return ReloCore.encodedIdToResource(reloRepo, "relo-eclipseProj#", proj.getName());
    }

    public static IProject resourceToEclipseProject(ReloRdfRepository reloRepo, Resource res) {
        if (res==null) return null;
        return ResourcesPlugin.getWorkspace().getRoot().getProject(resourceToId(reloRepo, res, false));
    }

    public static Resource eclipseResourceToRDFResource(ReloRdfRepository reloRepo, IResource res) {
        if (res==null) return null;
        return ReloCore.encodedIdToResource(reloRepo, "relo-eclipse#", res.getProjectRelativePath().toString());
    }
    
	// TODO: implement a version of the below that does not need a project as a
	// param (but gets the project by going up the containment of the given
	// resource)
    public static IResource resourceToEclipseResource(ReloRdfRepository reloRepo, Resource res, IProject proj) {
    	if (res==null) return null;
    	String id = resourceToId(reloRepo, res, false);
    	IFile file = proj.getFile(id);
    	return file;
    }
    
    public void initRepository(ReloRdfRepository reloRepo) {
        String reloPID = ReloCore.PLUGIN_ID;

        reloRepo.addStatement(ReloCore.commentType, ReloCore.model, StoreUtil.getClassLoc(reloPID, Comment.class));
        reloRepo.addStatement(ReloCore.commentType, ReloCore.controller, StoreUtil.getClassLoc(reloPID, CommentEditPart.class));

        reloRepo.addStatement(ReloCore.namedRel, ReloCore.model, StoreUtil.getClassLoc(reloPID, NamedRel.class));
        reloRepo.addStatement(ReloCore.namedRel, ReloCore.controller, StoreUtil.getClassLoc(reloPID, NamedRelationPart.class));
    }

}
